package com.mt.sdk.ble;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import com.mt.sdk.tools.MTTools;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.bluetooth.BluetoothAdapter.LeScanCallback;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.ParcelUuid;

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public class MTBLEManager {
	private static MTBLEManager mMTBLEManager;
	public BluetoothManager mBluetoothManager;
	public BluetoothAdapter mBluetoothAdapter;
	public Handler handl;

	private Scan5_0 mScan5_0;
	private Scan4_3 mScan4_3;

	private MTBLEManager() {
	}

	public static MTBLEManager getInstance(Context context) {
		if (mMTBLEManager == null) {

			if (android.os.Build.VERSION.SDK_INT < 18) {
				return null;
			}

			mMTBLEManager = new MTBLEManager();
			mMTBLEManager.init(context);
		}
		return mMTBLEManager;
	}

	// 初始化
	private void init(Context context) {
		this.mBluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
		this.mBluetoothAdapter = mBluetoothManager.getAdapter();

		handl = new Handler();

		if (android.os.Build.VERSION.SDK_INT < 21) {
			mScan4_3 = new Scan4_3(this.mBluetoothAdapter);
		} else {
			mScan5_0 = new Scan5_0(this.mBluetoothAdapter);
		}
	}

	// 是否可以工作
	public boolean canWork() {
		if ((mBluetoothManager == null) || (null == mBluetoothAdapter)) {
			return false;
		}
		return true;
	}

	// 开关蓝牙
	public boolean enable(boolean flag) {

		if (!canWork()) {
			return false;
		}

		if (flag) {
			mBluetoothAdapter.enable();
		} else {
			mBluetoothAdapter.disable();
		}

		return true;
	}

	// 是否使能
	public boolean isEnable() {
		if (!canWork()) {
			return false;
		}
		return mBluetoothAdapter.isEnabled();
	}

	// 获取自身mac
	public String getSelfMac() {
		if (mBluetoothAdapter == null) {
			return null;
		}
		return mBluetoothAdapter.getAddress();
	}

	// 扫描回调方法
	public interface MTScanCallback {
		public void onScan(MTBLEDevice device);

		public void onScanFail(int errocode, String erromsg);
	}

	// 开始扫描
	private MTScanCallback scanCallback;
	private boolean scan_flag = false;

	public boolean startScan(MTScanCallback scanCallback) {
		MTTools.logout("开始扫描");
		if (!mMTBLEManager.isEnable()) {
			scan_flag = false;
			return false;
		}

		if (scan_flag) {
			__stopScan();
		}

		scan_flag = true;
		this.scanCallback = scanCallback;

		__startScan();

		return true;
	}

	public boolean startScan(ScanMode scanmode, UUID[] serviceUuids, MTScanCallback scanCallback) {
		MTTools.logout("开始扫描");
		if (!mMTBLEManager.isEnable()) {
			scan_flag = false;
			return false;
		}

		if (scan_flag) {
			__stopScan();
		}

		scan_flag = true;
		this.scanCallback = scanCallback;

		__startScan(scanmode, serviceUuids);

		return true;
	}

	// 扫描
	@SuppressLint("NewApi")
	private boolean __startScan() {

		if (android.os.Build.VERSION.SDK_INT < 21) {
			mScan4_3.startScan(scanCallback);
		} else {
			mScan5_0.startScan(scanCallback);
		}

		return true;
	}

	@SuppressLint("NewApi")
	private boolean __startScan(ScanMode scanmode, UUID[] uuids) {

		if (android.os.Build.VERSION.SDK_INT < 21) {
			mScan4_3.startScan(uuids, scanCallback);
		} else {
			mScan5_0.startScan(scanmode, uuids, scanCallback);
		}

		return true;
	}

	// 停止扫描
	public boolean stopScan() {
		MTTools.logout("停止扫描");
		if (!mMTBLEManager.isEnable()) {
			scan_flag = false;
			return false;
		}

		if (scan_flag) {
			__stopScan();
		}
		scan_flag = false;

		return true;
	}

	private boolean __stopScan() {
		if (android.os.Build.VERSION.SDK_INT < 21) {
			System.out.println("mScan4_3.stopScan");
			mScan4_3.stopScan();
		} else {
			mScan5_0.stopScan();
		}

		return true;
	}

	// 是否正在扫描
	public boolean isScaning() {
		return scan_flag;
	}

	// 清除连接信息
	public boolean refreshGattStructure(BluetoothGatt gatt) {
		BluetoothGatt localGatt = gatt;
		try {
			Method localMethod = localGatt.getClass().getMethod("refresh", new Class[0]);
			if (localMethod != null) {
				boolean result = ((Boolean) localMethod.invoke(localGatt, new Class[0])).booleanValue();
				return result;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	// 安卓5.0+系统扫描方式
	@TargetApi(Build.VERSION_CODES.LOLLIPOP)
	private class Scan5_0 {
		private BluetoothAdapter mBluetoothAdapter;
		private MTScanCallback scanCallback;

		public Scan5_0(BluetoothAdapter mBluetoothAdapter) {
			this.mBluetoothAdapter = mBluetoothAdapter;
		}

		// 5.0+系统扫描回调方法
		private ScanCallback mScanCallback = new ScanCallback() {

			@Override
			public void onScanResult(final int callbackType, final ScanResult result) {
				super.onScanResult(callbackType, result);
				if (result == null) {
					return;
				}
				handl.post(new Runnable() {

					@Override
					public void run() {
						if (scanCallback == null) {
							return;
						}
						scanCallback.onScan(new MTBLEDevice(result.getDevice(), result.getScanRecord().getBytes(),
								result.getRssi()));
					}
				});
			}

			@Override
			public void onBatchScanResults(List<ScanResult> results) {
				super.onBatchScanResults(results);
			}

			@Override
			public void onScanFailed(int errorCode) {
				super.onScanFailed(errorCode);

				if (scanCallback == null) {
					return;
				}

				switch (errorCode) {
				case SCAN_FAILED_ALREADY_STARTED:
					scanCallback.onScanFail(1, "已经开启了扫描");
					break;
				case SCAN_FAILED_APPLICATION_REGISTRATION_FAILED:
					scanCallback.onScanFail(2, "应用程序没有注册");
					break;

				case SCAN_FAILED_FEATURE_UNSUPPORTED:
					scanCallback.onScanFail(3, "此设备不支持BLE");
					break;

				case SCAN_FAILED_INTERNAL_ERROR:
					scanCallback.onScanFail(3, "内部错误");
					break;

				default:
					scanCallback.onScanFail(0, "未知错误");
					break;
				}
			}

		};

		public boolean startScan(MTScanCallback scanCallback) {
			System.out.println("5.0 scan");
			this.scanCallback = scanCallback;
			if (scanCallback == null) {
				return false;
			}

			BluetoothLeScanner scaner = mBluetoothAdapter.getBluetoothLeScanner();
			scaner.startScan(null, new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build(),
					mScanCallback);

			return true;
		}

		public boolean startScan(ScanMode scanmode, UUID[] serviceUuids, MTScanCallback scanCallback) {
			System.out.println("5.0 scan");
			this.scanCallback = scanCallback;
			if (scanCallback == null) {
				return false;
			}

			List<ScanFilter> filters = new ArrayList<ScanFilter>();
			if(serviceUuids != null){
				for (UUID uuid2 : serviceUuids) {
					filters.add(new ScanFilter.Builder().setServiceUuid(new ParcelUuid(uuid2)).build());
				}
			}

			BluetoothLeScanner scaner = mBluetoothAdapter.getBluetoothLeScanner();
			
			int model = ScanSettings.SCAN_MODE_LOW_LATENCY;
			if(scanmode == ScanMode.LOWPOWER){
				model = ScanSettings.SCAN_MODE_LOW_POWER;
			}else if(scanmode == ScanMode.BLANCE){
				model = ScanSettings.SCAN_MODE_BALANCED;
			}else{
				model = ScanSettings.SCAN_MODE_LOW_LATENCY;
			}
			
			scaner.startScan(filters,
					new ScanSettings.Builder().setScanMode(model).build(), mScanCallback);

			return true;
		}

		public boolean stopScan() {
			this.scanCallback = null;

			BluetoothLeScanner scaner = mBluetoothAdapter.getBluetoothLeScanner();
			scaner.stopScan(mScanCallback);

			return true;
		}
	}

	// 安卓4.3+系统扫描方式
	private class Scan4_3 {
		private BluetoothAdapter mBluetoothAdapter;
		private MTScanCallback scanCallback;

		// 4.3-5.0系统扫描回调方法
		private LeScanCallback lescancallback = new LeScanCallback() {

			@Override
			public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
				handl.post(new Runnable() {

					@Override
					public void run() {
						if (scanCallback == null) {
							return;
						}
						scanCallback.onScan(new MTBLEDevice(device, scanRecord, rssi));
					}
				});

				return;
			}
		};

		public Scan4_3(BluetoothAdapter mBluetoothAdapter) {
			this.mBluetoothAdapter = mBluetoothAdapter;
		}

		public boolean startScan(MTScanCallback scanCallback) {
			System.out.println("4.3 scan");
			this.scanCallback = scanCallback;
			if (scanCallback == null) {
				return false;
			}
			this.mBluetoothAdapter.startLeScan(lescancallback);
			return true;
		}

		public boolean startScan(UUID[] serviceUuids, MTScanCallback scanCallback) {
			System.out.println("4.3 scan");
			this.scanCallback = scanCallback;
			if (scanCallback == null) {
				return false;
			}
			this.mBluetoothAdapter.startLeScan(serviceUuids, lescancallback);
			return true;
		}

		public boolean stopScan() {
			this.scanCallback = null;
			this.mBluetoothAdapter.stopLeScan(lescancallback);
			return true;
		}
	}
	
	public static enum ScanMode{
		LOWPOWER, // 低功耗
		BLANCE,   // 平衡模式
		FAST      // 快速扫描
	}
}
